package com.zhl.study.configuration;

import com.alibaba.fastjson.JSONObject;
import com.zhl.study.base.ArgumentsInvalidResponseBean;
import com.zhl.study.base.ResponseFactory;
import com.zhl.study.base.Result;
import com.zhl.study.enums.SystemEnums;
import com.zhl.study.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.util.ArrayList;
import java.util.List;

/**
 * @description 全局异常处理器
 * @Author: z156940l@outlook.com
 * @className GlobalExceptionHandler
 * @Date: 2023/4/28 10:49
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public Result httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException e) {
        log.error("http请求的方法不正确:【{}】", e.getMessage(), e);
        return ResponseFactory.fail(SystemEnums.REQUEST_METHOD_NOT_VALID, null);
    }

    @ResponseBody
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
        log.error("http请求参数格式不正确:【{}】", e.getMessage(), e);
        return ResponseFactory.fail(SystemEnums.PARAM_NOT_VALID, null);
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public Result handleArgumentException(MethodArgumentTypeMismatchException e) {
        log.error("study-exception:【{}】", e.getMessage(), e);
        return ResponseFactory.fail(SystemEnums.REQUEST_METHOD_NOT_VALID, null);
    }

    /**
     * 依赖没有引入
     * @param e
     * @return
     */
//    @ResponseBody
//    @ExceptionHandler(BadSqlGrammarException.class)
//    public Result handleException(BadSqlGrammarException e) {
//        log.error("study-exception:【{}】", e.getMessage(), e);
//        //不对用户界面返回sql报错信息
//        return ResponseFactory.fail(SystemEnums.SQL_BAD, SystemEnums.FAIL.getMsg(), null);
//    }

//    @ResponseBody
//    @ExceptionHandler(DataIntegrityViolationException.class)
//    public Result handleSqlException(DataIntegrityViolationException e) {
//        log.error("study-exception:【{}】", e.getMessage(), e);
//        //不对用户界面返回sql报错信息
//        return ResponseFactory.fail(SystemEnums.SQL_BAD, SystemEnums.FAIL.getMsg(), null);
//    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Result methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        List<ArgumentsInvalidResponseBean> argumentsInvalidResponseBeanList = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < e.getBindingResult().getFieldErrors().size(); i++) {
            FieldError error = e.getBindingResult().getFieldErrors().get(i);
            ArgumentsInvalidResponseBean bean = new ArgumentsInvalidResponseBean();
            bean.setArgumentName(error.getField());
            bean.setExceptionMsg(error.getDefaultMessage());
            argumentsInvalidResponseBeanList.add(bean);
            stringBuilder.append("参数:[")
                    .append(error.getField())
                    .append("]")
                    .append(error.getDefaultMessage())
                    .append(";");
            if (i != e.getBindingResult().getFieldErrors().size() -1){
                stringBuilder.append("\\n");
            }
        }
        log.error("study-exception:【{}】", JSONObject.toJSONString(argumentsInvalidResponseBeanList));
        return new Result(SystemEnums.PARAM_NOT_VALID, stringBuilder.toString());
    }

    @ExceptionHandler(BizException.class)
    @ResponseBody
    public Result methodArgumentNotValidExceptionHandler(BizException e) {
        log.error("study-exception:【{}】", e.getMessage(), e);
        return ResponseFactory.fail(e.getError(), null);
    }

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public Result methodArgumentNotValidExceptionHandler(RuntimeException e) {
        log.error("study-exception:【{}】", e.getMessage(), e);
        return ResponseFactory.fail(SystemEnums.UNKNOWN_ERROR, e.getMessage());
    }
}
